# ```python
import os
import json
import numpy as np

def convert_polygon_to_yolo_segment(points, img_width, img_height):
    points = np.array(points)
    # 限制点到图像边界
    points[:, 0] = np.clip(points[:, 0], 0, img_width)
    points[:, 1] = np.clip(points[:, 1], 0, img_height)
    # 归一化坐标
    points[:, 0] /= img_width
    points[:, 1] /= img_height
    # 确保点数足够形成多边形
    if len(points) < 3:
        return None
    return points.flatten()

def json_to_yolo_segment(json_dir, output_dir, class_map):
    output_dir = os.path.normpath(output_dir)
    os.makedirs(output_dir, exist_ok=True)
    
    for json_file in os.listdir(json_dir):
        if json_file.endswith('.json'):
            json_path = os.path.join(json_dir, json_file)
            try:
                with open(json_path, 'r', encoding='utf-8') as f:
                    data = json.load(f)
                
                img_width = data['imageWidth']
                img_height = data['imageHeight']
                if img_width <= 0 or img_height <= 0:
                    print(f"错误: {json_file} 包含无效的图像尺寸: {img_width}x{img_height}")
                    continue
                
                txt_filename = os.path.splitext(json_file)[0] + '.txt'
                txt_path = os.path.join(output_dir, txt_filename)
                
                with open(txt_path, 'w', encoding='utf-8') as f:
                    for shape in data['shapes']:
                        if shape['shape_type'] == 'polygon' and shape['label'] in class_map:
                            if len(shape['points']) < 3:
                                print(f"警告: {json_file} 中的形状 {shape['label']} 点数不足，跳过")
                                continue
                            points = convert_polygon_to_yolo_segment(shape['points'], img_width, img_height)
                            if points is None:
                                print(f"警告: {json_file} 中的形状 {shape['label']} 无法生成有效多边形，跳过")
                                continue
                            class_id = class_map[shape['label']]
                            f.write(f"{class_id} {' '.join([f'{p:.6f}' for p in points])}\n")
                
                print(f"成功转换: {json_file} -> {txt_filename}")
            except Exception as e:
                print(f"处理 {json_file} 时出错: {str(e)}")

if __name__ == "__main__":
    os.environ["PYTHONUTF8"] = "1"  # 强制 UTF-8 编码
    json_directory = r"D:\YOLOv11\datasets\st-fu\train\la"  # JSON 文件目录
    output_directory = r"D:\YOLOv11\datasets\st-fu\train\labels"  # 输出目录
    class_map = {"舌头": 0}  # 类别映射
    json_to_yolo_segment(json_dir=json_directory, output_dir=output_directory, class_map=class_map)
# ```